<template>
  <div class="dashboard" style="min-width: 1000px; padding: 0 80px">
    <header class="top">
      <div class="selectors mt-2">
        <div class="flex items-center">
          <label class="font-bold text-white">目标市场</label>
          <div class="cursor-pointer rounded-full text-white font-bold"
               style="margin-left: 10px; padding-right: 10px; background: #ffffff11">
            <select v-model="market" class="cursor-pointer outline-0" style="padding: 12.5px 15px;">
              <option class="" v-for="m in markets" :key="m" :value="m">{{ m }}</option>
            </select>
          </div>
        </div>

        <div class="flex items-center ml-3">
          <label class="font-bold text-white">产品类别</label>
          <div class="cursor-pointer rounded-full  text-white font-bold"
               style="margin-left: 10px; padding-right: 10px; background: #ffffff11">
            <select v-model="category" class="cursor-pointer outline-0" style="padding: 12.5px 15px;">
              <option v-for="c in categories" :key="c" :value="c">{{ c }}</option>
              <!-- 动态生成类别选项 -->
            </select>
          </div>
        </div>
      </div>

    </header>

    <div class="keywords mb-5">
      <div class="flex">
        <div class="flex-1 py-1.5 px-1.5 rounded-full flex mr-3" style="background: #ffffff11">
          <div v-for="(k, i) in keywords" class="flex items-center">
            <span @click="selectKeyword(i)"
                  class="px-4 py-2.5 rounded-full mr-2 cursor-pointer select-none flex text-white"
                  :style="{
                    background: keyword_select === i ? '#ffffff11' : 'transparent'
                  }"
                  :key="k">
              <img class="w-4 mr-1" src="../../assets/img/select/file.svg" alt="">
              {{ k }}
              <button class="ml-2" @click.stop="removeKeyword(i)">×</button>
            </span>
            <div class="h-5 relative rounded-full transition w-0.5" :class="{
              'bg-gray-700': keyword_select < i || keyword_select > i+1,
              'bg-transparent': keyword_select >= i && keyword_select <= i+1,
            }"></div>
          </div>
        </div>
        <input v-model="newKeyword" class="mr-3 outline-0 px-3 pl-5 rounded-full w-36" style="background: #edf1fb"
               @keyup.enter="addKeyword"
               placeholder="添加关键字"/>
        <button class="add cursor-pointer select-none" @click="addKeyword">+ 关键词</button>
      </div>
    </div>

    <main class="content relative"
          :style="{
            opacity: keywords[keyword_select] === '空气炸锅' || keywords[keyword_select] === '迷你搅拌机' || keywords[keyword_select] === '电饭煲'? 1:0
          }">
      <section class="flex" style="min-width: 1140px">
        <div class="" style="flex: 1">
          <img src="../../assets/img/select/analyse.svg"
               class="rounded-2xl cursor-pointer select-none w-full" alt="">
        </div>

        <div class="mx-3 rounded-2xl flex flex-col"
             style="background: linear-gradient(180deg, #3435f5 0%, #5578e6 100%); flex: 1">
          <div class="flex justify-between px-5 py-4">
            <div class="text-transparent">全部></div>
            <div class="text-white font-bold text-xl">推荐商品</div>
            <div class="text-white opacity-60 cursor-pointer select-none">全部></div>
          </div>
          <div class="flex flex-1 items-center justify-evenly mb-4">
            <div v-for="p in competitors" :key="p.id" class="comp" @click="selectProduct(p)">
              <div class="bg-white w-12 h-12 overflow-hidden flex justify-center items-center rounded-md font-bold">
                <img :src="p.icon" alt="">
              </div>
              <div class="name text-white font-bold">{{ p.name }}</div>
            </div>
          </div>
        </div>

        <div class=" flex flex-col justify-center items-center rounded-2xl overflow-hidden bg-white"
             style=" flex: 1">
          <div style="background: #DC5E59" class=" text-white py-2 w-full text-center">{{ calendarTitle }}</div>
          <div class="flex-1 flex justify-center items-center text-6xl font-bold">
            {{ calDay }}
            <div class="text-lg w-4 ml-3 flex justify-center items-center" style="color: #DC5E59; line-height: 22px">
              {{ calWeekday }}
            </div>
          </div>
          <div class="mb-3">{{ calLunar }}</div>
        </div>
      </section>

      <section class="flex mb-20">
        <div class="  bg-white rounded-2xl px-5 py-4 flex-1" style="">
          <h3 class="font-bold text-gray-700 text-xl">市场趋势分析</h3>

          <div ref="trendDiv" class="echart"/>
          <div class="chart-actions">
            <select v-model="chartRange" class="outline-1 rounded outline-gray-200 text-gray-500 cursor-pointer">
              <option value="12">近12个月</option>
              <option value="24">近24个月</option>
              <option value="36">近36个月</option>
            </select>
          </div>
        </div>


        <div style="width: 480px" class="overflow-scroll bg-white rounded-2xl px-5 py-4 ml-3">
          <h3 class="font-bold text-gray-700 text-xl">指数趋势监测</h3>
          <div class="text-gray-400 mt-1 mb-4">由Agent自动发出</div>
          <div class="">
            <div class="flex mb-4"
                 v-for="(item_metric, idx_metric) in [metrics.rising, metrics.trending, metrics.risky]">
              <div class="mr-4 flex flex-col justify-center px-4 w-24 rounded-lg border cursor-pointer select-none"
                   :style="{
                color: ['#FF3838','#4B59F4','#FF8121'][idx_metric],
                background: ['rgba(255,56,56,0.15)','rgba(75,89,244,0.15)','rgba(255,129,33,0.15)'][idx_metric],
                borderColor: ['rgba(255,56,56,0.35)','rgba(75,89,244,0.35)','rgba(255,129,33,0.35)'][idx_metric],
              }">
                <div class="label font-bold">{{ ['上升很快', '多日在榜', '存在风险'][idx_metric] }}</div>
                <div class="num text-xl font-bold">{{ item_metric.count }}</div>
              </div>
              <div class="flex-1 overflow-scroll">
                <div class="flex flex-nowrap">
                  <div class="mr-4 flex flex-col items-center cursor-pointer select-none"
                       v-for="(item, idx) in item_metric.data" :key="idx">
                    <div
                        class="w-16 h-16 border rounded-md flex justify-center overflow-hidden items-center border-gray-300">
                      <img :src="item.short" alt="">
                    </div>
                    <div class="mt-2 font-bold text-gray-700">{{ item.name }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </main>

    <div class="absolute top-56 left-1/2 -translate-x-1/2"
         v-if="!(keywords[keyword_select] === '空气炸锅' || keywords[keyword_select] === '迷你搅拌机' || keywords[keyword_select] === '电饭煲')">
      <div class="flex flex-col justify-center items-center py-20">
        <div class="flex ">
          <svg t="1756286506946" class="icon" viewBox="0 0 1045 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
               p-id="7620" width="60" height="60">
            <path
                d="M889.3743 409.308952c9.671946-2.668123 20.010922-3.46856 30.572242-2.112264l31.150335 4.091122a100.588233 100.588233 0 0 1 86.491651 112.728193l-8.982681 68.415118a131.760803 131.760803 0 0 1-147.92518 113.461926c-2.223436-0.311281-4.446872-0.689265-6.603605-1.178421a348.056632 348.056632 0 0 1-99.520984 197.952485c-66.414026 66.414026-154.306441 102.989544-247.624039 102.989544h-163.044544a348.190039 348.190039 0 0 1-247.690743-102.989544A348.14557 348.14557 0 0 1 13.207208 655.79904L0 380.226413v-1.645343a48.915587 48.915587 0 0 1 48.915587-48.915586h792.966126a48.915587 48.915587 0 0 1 48.915586 48.915586v1.645343L889.3743 409.308952z m-822.382181-13.47402l12.317834 257.540563v1.667576a282.598684 282.598684 0 0 0 83.623419 200.954124 282.509747 282.509747 0 0 0 200.998592 83.601184h163.000075a282.598684 282.598684 0 0 0 200.976357-83.623419 282.509747 282.509747 0 0 0 83.601184-200.998592v-1.645342l12.340069-257.562797-756.85753 0.066703z m905.093991 119.531906v0.044468a34.418785 34.418785 0 0 0-29.616164-38.643313l-31.083632-4.046653a11.917616 11.917616 0 0 0-13.162739 10.072164l-19.010376 144.389918a11.895381 11.895381 0 0 0 10.094398 13.207208c36.019659 4.669215 69.015446-20.677952 73.773599-56.653143l9.004914-68.370649zM208.869554 755.431196a33.040255 33.040255 0 0 1-34.707832-31.261507l-7.737556-147.569431a33.040255 33.040255 0 0 1 65.991573-3.446325l7.737556 147.569431a33.040255 33.040255 0 0 1-31.283741 34.730066v-0.022234z m126.580198-516.014969l-0.333516-0.311281c10.894835 12.673584 10.650257 31.48385-0.600327 43.846153a33.040255 33.040255 0 0 1-43.557107 4.758152l-0.311281 0.333515a52.072865 52.072865 0 0 1-3.223981-3.11281 34.240911 34.240911 0 0 1-4.669216-5.314011 121.910982 121.910982 0 0 1-19.810812-34.352082c-8.98268-23.679591-15.119363-62.033857 6.714776-109.948898 10.294508-22.65681 12.740287-43.290294 7.226166-61.344593a53.251286 53.251286 0 0 0-8.271181-16.742471 33.040255 33.040255 0 1 1 47.581525-45.891714c2.312373 2.356842 55.585894 59.121157 13.629661 151.327037-9.449602 20.833593-11.472928 39.932906-5.936573 56.719846 2.356842 7.426275 6.314558 14.274458 11.561866 20.010922z m154.084097 0L489.155865 239.104946a33.040255 33.040255 0 0 1-44.157434 48.537602l-0.333515 0.333515a68.126071 68.126071 0 0 1-3.201748-3.11281 33.685052 33.685052 0 0 1-4.669215-5.314011 122.111091 122.111091 0 0 1-19.833047-34.352083c-8.960446-23.679591-15.074894-62.033857 6.737011-109.948897 10.294508-22.65681 12.718052-43.290294 7.226166-61.344593a52.873302 52.873302 0 0 0-8.271181-16.675768A33.040255 33.040255 0 1 1 470.256661 11.313953c2.290139 2.356842 55.585894 59.121157 13.651896 151.327037-9.494071 20.833593-11.495163 39.932906-5.958808 56.719846 2.356842 7.44851 6.314558 14.274458 11.561866 20.010922z m144.123106 0h-0.066703l-0.35575-0.289047a33.040255 33.040255 0 0 1-44.090731 48.582071l-0.311281 0.333515a58.943282 58.943282 0 0 1-3.201748-3.11281 33.685052 33.685052 0 0 1-4.669215-5.314011 121.866514 121.866514 0 0 1-19.833047-34.352082c-8.960446-23.679591-15.074894-62.033857 6.737011-109.948898 10.294508-22.65681 12.740287-43.290294 7.226166-61.344593a52.984474 52.984474 0 0 0-8.248947-16.742471 33.040255 33.040255 0 1 1 47.581525-45.891714c2.290139 2.356842 55.541425 59.121157 13.607427 151.327037-9.449602 20.833593-11.450694 39.932906-5.936573 56.719846 2.356842 7.44851 6.314558 14.274458 11.561866 20.010922z"
                fill="#2c2c2c" p-id="7621"></path>
          </svg>
        </div>
        <div class="mt-4">
          后台正在生成中，请稍后再来查看~
        </div>
      </div>
    </div>

    <!-- product modal -->
    <div class="modal" v-if="activeProduct">
      <div class="modal-inner">
        <div class="close mr-3 mt-3 cursor-pointer select-none" @click="activeProduct = null">
          <div class="">
            <svg t="1756285799974" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                 p-id="5643" width="18" height="18">
              <path
                  d="M801.645714 170.666667l51.833905 51.590095L565.150476 511.951238l288.353524 289.670095-51.833905 51.614477-288.109714-289.450667L225.426286 853.23581 173.592381 801.621333l288.329143-289.670095L173.592381 222.256762 225.426286 170.666667l288.109714 289.426285L801.645714 170.666667z"
                  p-id="5644" fill="#2c2c2c"></path>
            </svg>
          </div>
        </div>
        <h3 class="text-2xl font-bold mb-2">{{ activeProduct.name }}</h3>
        <p>价格：{{ activeProduct.price }}</p>
        <div v-if="activeProduct.hot_index" class="hot-index">
          <p>热度指数：{{ activeProduct.hot_index }}/100</p>
        </div>
        <p>简介：{{ activeProduct.description }}</p>
        <div v-if="activeProduct.history_hot_index" class="history-hot-index mt-3 mb-2">
          <h4 class="text-lg font-bold mb-2">历史热度指数</h4>
          <ul>
            <li v-for="(value, period) in activeProduct.history_hot_index" :key="period">
              {{ period }}: {{ value }}/100
            </li>
          </ul>
        </div>
        <div @click="toPromote"
             class="text-base bg-blue-600 px-10 py-3 text-center mt-8 text-white font-bold rounded-full cursor-pointer select-none">
          前往营销页面
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {ref, reactive, onMounted, watch, onBeforeUnmount, computed} from 'vue'
import * as echarts from 'echarts'
import lunarCal from "lunar-calendar";

// 市场和类别数据
const markets = ['东南亚市场', '北美市场', '欧洲市场']
const allCategories = {
  '东南亚市场': ['小家电', '家居用品', '数码电子', '办公用品', '包包饰品', '美妆', '食品'],
  '北美市场': ['健身器材'],
  '欧洲市场': ['家居用品']
}

const market = ref(markets[0])
const category = ref('小家电')

const is_generating_data = ref(false)

const toPromote = () => {
  window.location.href = "/promote"
}

// 监听市场变化，动态更新类别选项
watch(market, (newMarket) => {
  const categories = allCategories[newMarket] || []
  if (categories.length > 0) {
    category.value = categories[0]
  }
})

const categories = computed(() => {
  return allCategories[market.value] || []
})

const selectKeyword = async (i) => {
  keyword_select.value = i

  // updateKeywords()
  updateCompetitors()
  renderChart()

  setTimeout(() => {
    // regenerateChart()
  }, 200)
}

const keyword_select = ref(0)

const show_add_keyword_input = ref(false)

// 根据市场和类别动态生成关键词
const keywords = ref(['空气炸锅'])
const newKeyword = ref('')

watch([market, category], () => {
  updateKeywords()
})

function updateKeywords() {
  // 根据当前市场和类别生成关键词
  if (market.value === '东南亚市场' && category.value === '小家电') {
    keywords.value = ['空气炸锅', '迷你搅拌机', '电饭煲']
  } else if (market.value === '北美市场' && category.value === '健身器材') {
    keywords.value = ['跑步机', '划船机']
  } else if (market.value === '欧洲市场' && category.value === '家居用品') {
    keywords.value = ['LED灯泡', '智能恒温器']
  } else {
    keywords.value = ['商品']
  }
  keyword_select.value = 0
}

function addKeyword() {
  const k = newKeyword.value && newKeyword.value.trim()
  if (k && keywords.value.indexOf(k) === -1) {
    keywords.value.push(k)
    keyword_select.value = keywords.value.length - 1
  }
  newKeyword.value = ''
}

async function removeKeyword(i) {
  if (keywords.value.length <= 1) {
    return
  }
  keywords.value.splice(i, 1)
  setTimeout(() => {
    keyword_select.value = 0
  }, 50)
}

import img_1 from "../../assets/img/select/图片1.png"
import img_2 from "../../assets/img/select/图片2.png"
import img_3 from "../../assets/img/select/图片3.png"
import img_4 from "../../assets/img/select/图片4.png"
import img_5 from "../../assets/img/select/图片5.png"
import img_6 from "../../assets/img/select/图片6.png"
import img_7 from "../../assets/img/select/图片7.png"
import router from "@/router/index.js";
import {useRouter} from "vue-router";

// 产品数据
const productData = {
  '东南亚市场': {
    '小家电': [
      {
        id: 'air_fryer',
        name: '空气炸锅',
        short: 'AF',
        icon: img_1,
        price: '399人民币',
        description: '【2024升级款】6.5L大容量智能空气炸锅 - 无需用油，健康炸烤！360°循环加热 | 触控屏 | 预设8菜单 | 易清洗 | 适用于家庭聚餐',
        hot_index: 92,
        history_hot_index: {
          '2010-2014': '75',
          '2015-2018': '82',
          '2019-2021': '99',
          '2022-2023': '90',
          '2024-(预计)': '88'
        }
      },
      {
        id: 'blender',
        name: '迷你搅拌机',
        short: 'MB',
        icon: img_2,
        price: '79人民币',
        description: '**绞肉料理机捣蒜器家用小型迷你搅碎机辅食蒜泥烹饪机无线便携',
        hot_index: 87,
        history_hot_index: {
          '2015-2017': '78',
          '2018-2020': '85',
          '2021-2023': '92',
          '2024-(预计)': '88'
        }
      },
      {
        id: 'rice_cooker',
        name: '电饭煲',
        short: 'RC',
        icon: img_3,
        price: '795人民币',
        description: '**新品Xtra零零煲青春版家用4L电饭煲煮饭0涂层4-6人电饭锅烹饪',
        hot_index: 85,
        history_hot_index: {
          '1950s-1990s': '85',
          '2000-2010': '80',
          '2011-2016': '82',
          '2017-2021': '88',
          '2022-2024': '86'
        }
      }
    ]
  },
  '北美市场': {
    '健身器材': [
      {
        id: 'treadmill',
        name: '跑步机',
        short: 'TM',
        icon: img_4,
        price: '3319人民币',
        description: '**A8跑步机家用款健身房专用可折叠超静音爬坡机女室内大型男士',
        hot_index: 83,
        history_hot_index: {
          '2015-2019': '78',
          '2020-2021': '99',
          '2022-2023': '75',
          '2024-(预计)': '82'
        }
      },
      {
        id: 'rowing_machine',
        name: '划船机',
        short: 'RM',
        icon: img_5,
        price: '2419人民币',
        description: '***950划船机家用可折叠水磁双阻多功能智能有氧健身运动器材',
        hot_index: 88,
        history_hot_index: {
          '2015-2017': '72',
          '2018-2019': '80',
          '2020-2021': '98',
          '2022-2023': '84',
          '2024-(预计)': '86'
        }
      }
    ]
  },
  '欧洲市场': {
    '家居用品': [
      {
        id: 'led_bulb',
        name: 'LED灯泡',
        short: 'LB',
        icon: img_6,
        price: '6.5人民币',
        description: '**灯泡e27螺口led家用节能灯电灯泡e14螺旋口白炽灯替换球泡灯',
        hot_index: 79,
        history_hot_index: {
          '2008-2012': '65',
          '2013-2016': '85',
          '2017-2020': '92',
          '2021-2023': '78',
          '2024-(预计)': '80'
        }
      },
      {
        id: 'thermostat',
        name: '智能恒温器',
        short: 'ST',
        icon: img_7,
        price: '81.2人民币',
        description: '**温控器鱼缸温控开关控制器控温器数显智能全自动温控插座高清',
        hot_index: 82,
        history_hot_index: {
          '2011-2013': '75',
          '2014-2016': '82',
          '2017-2019': '85',
          '2020-2022': '88',
          '2023-2024(预计)': '90'
        }
      }
    ]
  }
}

const competitors = ref([])

// 根据市场和类别更新竞品数据
function updateCompetitors() {
  const products = productData[market.value]?.[category.value] || []
  competitors.value = products.map(product => ({
    ...product,
    icon: product.icon || '../../assets/img/select/air_fryer/空气炸锅01.png'
  }))
}

// 监听市场和类别变化，更新竞品数据
watch([market, category], updateCompetitors)

const activeProduct = ref(null)

function selectProduct(p) {
  activeProduct.value = p
}

function showAllCompetitors() {
  alert('打开全部竞对列表（示例）')
}

function watchProduct(p) {
  alert(`已添加 ${p.name} 到监控`)
}

function compareWithCompetitors(p) {
  alert(`正在和竞品对比：${p.name}`)
}

/* 公历转农历代码思路：
1、建立农历年份查询表
2、计算输入公历日期与公历基准的相差天数
3、从农历基准开始遍历农历查询表，计算自农历基准之后每一年的天数，并用相差天数依次相减，确定农历年份
4、利用剩余相差天数以及农历每个月的天数确定农历月份
5、利用剩余相差天数确定农历哪一天 */

// 农历1949-2100年查询表
function sloarToLunar(sy, sm, sd) {
  let lunarYearArr = [
        0x0b557, //1949
        0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
        0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969
        0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979
        0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989
        0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999
        0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
        0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019
        0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029
        0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039
        0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049
        0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
        0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
        0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
        0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
        0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
        0x0d520 //2100
      ],
      lunarMonth = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'],
      lunarDay = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初', '廿'],
      tianGan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
      diZhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];

  // 公历转农历函数
  function sloarToLunar(sy, sm, sd) {
    // 输入的月份减1处理
    sm -= 1;

    // 计算与公历基准的相差天数
    // Date.UTC()返回的是距离公历1970年1月1日的毫秒数,传入的月份需要减1
    let daySpan = (Date.UTC(sy, sm, sd) - Date.UTC(1949, 0, 29)) / (24 * 60 * 60 * 1000) + 1;
    let ly, lm, ld, lz = getZodiac(sy);
    // 确定输出的农历年份
    for (let j = 0; j < lunarYearArr.length; j++) {
      daySpan -= lunarYearDays(lunarYearArr[j]);
      if (daySpan <= 0) {
        ly = 1949 + j;
        // 获取农历年份确定后的剩余天数
        daySpan += lunarYearDays(lunarYearArr[j]);
        break
      }
    }

    // 确定输出的农历月份
    for (let k = 0; k < lunarYearMonths(lunarYearArr[ly - 1949]).length; k++) {
      daySpan -= lunarYearMonths(lunarYearArr[ly - 1949])[k];
      if (daySpan <= 0) {
        // 有闰月时，月份的数组长度会变成13，因此，当闰月月份小于等于k时，lm不需要加1
        if (hasLeapMonth(lunarYearArr[ly - 1949]) && hasLeapMonth(lunarYearArr[ly - 1949]) <= k) {
          if (hasLeapMonth(lunarYearArr[ly - 1949]) < k) {
            lm = k;
          } else if (hasLeapMonth(lunarYearArr[ly - 1949]) === k) {
            lm = '闰' + k;
          } else {
            lm = k + 1;
          }
        } else {
          lm = k + 1;
        }
        // 获取农历月份确定后的剩余天数
        daySpan += lunarYearMonths(lunarYearArr[ly - 1949])[k];
        break
      }
    }

    // 确定输出农历哪一天
    ld = daySpan;

    // 将计算出来的农历月份转换成汉字月份，闰月需要在前面加上闰字
    if (hasLeapMonth(lunarYearArr[ly - 1949]) && (typeof (lm) === 'string' && lm.indexOf('闰') > -1)) {
      lm = `闰${lunarMonth[/\d/.exec(lm) - 1]}`
    } else {
      lm = lunarMonth[lm - 1];
    }

    // 将计算出来的农历年份转换为天干地支年
    ly = getTianGan(ly) + getDiZhi(ly);

    // 将计算出来的农历天数转换成汉字
    if (ld < 11) {
      ld = `${lunarDay[10]}${lunarDay[ld - 1]}`
    } else if (ld > 10 && ld < 20) {
      ld = `${lunarDay[9]}${lunarDay[ld - 11]}`
    } else if (ld === 20) {
      ld = `${lunarDay[1]}${lunarDay[9]}`
    } else if (ld > 20 && ld < 30) {
      ld = `${lunarDay[11]}${lunarDay[ld - 21]}`
    } else if (ld === 30) {
      ld = `${lunarDay[2]}${lunarDay[9]}`
    }


    return {
      lunarYear: ly,
      lunarMonth: lm,
      lunarDay: ld,
      lunarZodiac: lz
    }
  }

  // 计算农历年是否有闰月，参数为存储农历年的16进制
  // 农历年份信息用16进制存储，其中16进制的最后1位可以用于判断是否有闰月
  function hasLeapMonth(ly) {
    // 获取16进制的最后1位，需要用到&与运算符
    if (ly & 0xf) {
      return ly & 0xf
    } else {
      return false
    }
  }

  // 如果有闰月，计算农历闰月天数，参数为存储农历年的16进制
  // 农历年份信息用16进制存储，其中16进制的第1位（0x除外）可以用于表示闰月是大月还是小月
  function leapMonthDays(ly) {
    if (hasLeapMonth(ly)) {
      // 获取16进制的第1位（0x除外）
      return (ly & 0xf0000) ? 30 : 29
    } else {
      return 0
    }
  }

  // 计算农历一年的总天数，参数为存储农历年的16进制
  // 农历年份信息用16进制存储，其中16进制的第2-4位（0x除外）可以用于表示正常月是大月还是小月
  function lunarYearDays(ly) {
    let totalDays = 0;

    // 获取正常月的天数，并累加
    // 获取16进制的第2-4位，需要用到>>移位运算符
    for (let i = 0x8000; i > 0x8; i >>= 1) {
      let monthDays = (ly & i) ? 30 : 29;
      totalDays += monthDays;
    }
    // 如果有闰月，需要把闰月的天数加上
    if (hasLeapMonth(ly)) {
      totalDays += leapMonthDays(ly);
    }

    return totalDays
  }

  // 获取农历每个月的天数
  // 参数需传入16进制数值
  function lunarYearMonths(ly) {
    let monthArr = [];

    // 获取正常月的天数，并添加到monthArr数组中
    // 获取16进制的第2-4位，需要用到>>移位运算符
    for (let i = 0x8000; i > 0x8; i >>= 1) {
      monthArr.push((ly & i) ? 30 : 29);
    }
    // 如果有闰月，需要把闰月的天数加上
    if (hasLeapMonth(ly)) {
      monthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly));
    }

    return monthArr
  }

  // 将农历年转换为天干，参数为农历年
  function getTianGan(ly) {
    let tianGanKey = (ly - 3) % 10;
    if (tianGanKey === 0) tianGanKey = 10;
    return tianGan[tianGanKey - 1]
  }

  // 将农历年转换为地支，参数为农历年
  function getDiZhi(ly) {
    let diZhiKey = (ly - 3) % 12;
    if (diZhiKey === 0) diZhiKey = 12;
    return diZhi[diZhiKey - 1]
  }

  function getZodiac(year) {
    const zodiac = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
    return zodiac[(year - 1900) % 12];
  }

  return sloarToLunar(sy, sm, sd)
}


function getCurrentLunarDate() {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth() + 1; // 月份从0开始，需要+1
  const day = now.getDate();
  const lunar = lunarCal.solarToLunar(year, month, day);
  return lunar.GanZhiYear + lunar.zodiac + "年" + " " + lunar.lunarMonthName + lunar.lunarDayName
}


// calendar
const now = new Date()
const calendarTitle = `${now.getFullYear()}年${now.getMonth() + 1}月`
const calDay = now.getDate()
const calWeekday = '周' + ['日', '一', '二', '三', '四', '五', '六'][now.getDay()]
const calLunar = getCurrentLunarDate() // placeholder

// index cards
const metrics = reactive({
  rising: {
    count: 28,
    data: [
      {
        id: 'A',
        name: '空气炸锅',
        short: 'https://img0.baidu.com/it/u=449724661,3256071151&fm=253&fmt=auto&app=120&f=JPEG?w=502&h=500'
      },
      {
        id: 'B',
        name: '智能跳绳',
        short: 'https://img0.baidu.com/it/u=1396235208,2247510765&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500'
      },
      {
        id: 'C',
        name: '蓝牙耳机',
        short: 'https://img0.baidu.com/it/u=332535020,270546477&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
      },
      {
        id: 'D',
        name: '豆浆机',
        short: 'https://img1.baidu.com/it/u=3203160043,2118016872&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500'
      }
    ]
  },
  trending: {
    count: 348,
    data: [
      {
        id: 'E',
        name: '智能手环',
        short: 'https://img0.baidu.com/it/u=3370777373,2825530162&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500'
      },
      {
        id: 'F',
        name: '空气炸锅',
        short: 'https://img0.baidu.com/it/u=449724661,3256071151&fm=253&fmt=auto&app=120&f=JPEG?w=502&h=500'
      },
      {
        id: 'G',
        name: '体重秤',
        short: 'https://img2.baidu.com/it/u=6753300,3130309006&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=513'
      },
      {
        id: 'H',
        name: '头颈仪',
        short: 'https://img1.baidu.com/it/u=1930302641,2740898402&fm=253&fmt=auto&app=138&f=JPEG?w=510&h=500'
      }
    ]
  },
  risky: {
    count: 23,
    data: [
      {
        id: 'I',
        name: '养生壶',
        short: 'https://img0.baidu.com/it/u=973686826,2675157059&fm=253&fmt=auto&app=120&f=JPEG?w=555&h=500'
      },
      {
        id: 'J',
        name: '电动牙刷',
        short: 'https://img1.baidu.com/it/u=2984092034,1464561432&fm=253&fmt=auto&app=120&f=JPEG?w=750&h=500'
      },
      {
        id: 'K',
        name: '剃须刀',
        short: 'https://img0.baidu.com/it/u=28991440,2246838159&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
      },
      {
        id: 'K',
        name: '筋膜枪',
        short: 'https://img1.baidu.com/it/u=3965389291,483153906&fm=253&fmt=auto&app=120&f=PNG?w=541&h=500'
      },
    ]
  }
})

// echart
const trendDiv = ref(null)
let trendChart = null
const chartRange = ref(24) // 默认改为24个月


// 生成并缓存36个月的完整数据集
function generateAndCacheFullData() {
  const storageKey = 'chartData_full36months';

  // 尝试从localStorage中获取已存储的数据
  const cachedData = localStorage.getItem(storageKey);
  if (cachedData) {
    try {
      const parsedData = JSON.parse(cachedData);
      // 验证数据格式是否正确
      if (Array.isArray(parsedData) && parsedData.length === 3 &&
          Array.isArray(parsedData[0]) && Array.isArray(parsedData[1]) && Array.isArray(parsedData[2])) {
        return parsedData;
      }
    } catch (e) {
      // 解析失败，继续生成新数据
      console.warn('Failed to parse cached chart data, generating new data');
    }
  }

  // 如果没有缓存数据或解析失败，则生成新数据
  const seriesA = randomSeries(36);
  const seriesB = randomSeries(36);
  const seriesC = randomSeries(36);

  // 将新生成的数据存储到localStorage中
  const newData = [seriesA, seriesB, seriesC];
  localStorage.setItem(storageKey, JSON.stringify(newData));

  return newData;
}

// 根据选择的时间范围截取数据
function getSlicedData(months) {
  // 获取完整的36个月数据
  const [fullSeriesA, fullSeriesB, fullSeriesC] = generateAndCacheFullData();

  // 根据选择的时间范围截取数据
  if (months === 36) {
    return [fullSeriesA, fullSeriesB, fullSeriesC];
  } else if (months === 24) {
    // 取最近24个月的数据（数组后24个元素）
    return [
      fullSeriesA.slice(12),
      fullSeriesB.slice(12),
      fullSeriesC.slice(12)
    ];
  } else if (months === 12) {
    // 取最近12个月的数据（数组后12个元素）
    return [
      fullSeriesA.slice(24),
      fullSeriesB.slice(24),
      fullSeriesC.slice(24)
    ];
  }

  // 默认返回全部数据
  return [fullSeriesA, fullSeriesB, fullSeriesC];
}

// 生成随机数据序列的函数（保持原有逻辑）
function randomSeries(len) {
  const arr = []
  let v = Math.random() * 10000 + 5000
  for (let i = 0; i < len; i++) {
    v += Math.random() * 2000 - 500
    arr.push(Math.max(1000, Math.round(v + Math.random() * 2000)))
  }
  return arr
}

// 修改buildOption函数以使用包含关系的数据
function buildOption() {
  const months = Number(chartRange.value)
  const now = new Date()
  const labels = []

  // 生成月份标签 (年份+月份格式)
  for (let i = months - 1; i >= 0; i--) {
    const date = new Date(now.getFullYear(), now.getMonth() - i, 1)
    labels.push(`${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`)
  }

  // 使用具有包含关系的数据
  const [seriesA, seriesB, seriesC] = getSlicedData(months)

  return {
    color: ['#3B82F6', '#06B6D4', '#A78BFA'],
    tooltip: {trigger: 'axis'},
    legend: {bottom: 0},
    grid: {left: '6%', right: '6%', top: '10%', bottom: '12%'},
    xAxis: {type: 'category', data: labels, boundaryGap: false},
    yAxis: {type: 'value'},
    series: [
      {name: '空气炸锅', type: 'line', data: seriesA, smooth: true},
      {name: '迷你搅拌机', type: 'line', data: seriesB, smooth: true},
      {name: '电饭煲', type: 'line', data: seriesC, smooth: true}
    ]
  }
}

// 添加清除缓存的函数
function clearChartDataCache() {
  localStorage.removeItem('chartData_full36months');
  // 重新生成当前图表
  renderChart();
}

function renderChart() {
  if (!trendDiv.value) return
  if (!trendChart) trendChart = echarts.init(trendDiv.value)
  const option = buildOption()
  trendChart.setOption(option)
}

function regenerateChart() {
  renderChart()
}


onMounted(() => {
  updateKeywords()
  updateCompetitors()
  renderChart()
  window.addEventListener('resize', onResize)
})

function onResize() {
  if (trendChart) trendChart.resize()
}

onBeforeUnmount(() => {
  if (trendChart) {
    trendChart.dispose()
    trendChart = null
  }
  window.removeEventListener('resize', onResize)
})

watch(chartRange, () => renderChart())
</script>

<style scoped>
.dashboard {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
  padding: 18px;
  background: #111213;
  color: #111
}

.top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px
}

.selectors {
  display: flex;
  gap: 18px;
  align-items: center
}


.select-group label {
  font-size: 13px;
  color: #333
}

.select-group select {
  padding: 8px 10px;
  border-radius: 18px;
  border: 1px solid #e2e8f0
}

.keywords {
  display: flex;
  flex-direction: column
}

.chips {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 6px
}

.chip {
  background: #eef3ff;
  padding: 6px 10px;
  border-radius: 16px
}

.chip button {
  background: transparent;
  border: 0;
  margin-left: 6px;
  cursor: pointer
}

.chips input {
  padding: 6px 8px;
  border-radius: 12px;
  border: 1px solid #ddd
}

.add {
  padding: 6px 10px;
  border-radius: 12px;
  background: #2b6bf2;
  color: white;
  border: 0
}

.top-actions .ai-btn {
  background: linear-gradient(90deg, #1e40af, #2563eb);
  color: white;
  padding: 10px 18px;
  border-radius: 12px;
  border: 0;
  cursor: pointer
}

.content {
  display: flex;
  flex-direction: column;
  gap: 18px
}

.cards-row {
  display: flex;
  gap: 18px
}

.card {
  background: white;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 1px 3px rgba(16, 24, 40, 0.05);
  flex: 1
}

.ai-card {
  flex: 2
}

.recommended {
  display: flex;
}

.rec-list {
  display: flex;
  gap: 12px;
  margin-top: 8px
}

.rec-item {
  display: flex;
  gap: 10px;
  align-items: center;
  background: #f8fafc;
  padding: 8px;
  border-radius: 10px;
  cursor: pointer
}

.rec-item img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 8px
}

.rec-item .title {
  font-weight: 600
}

.competitors .comp-list {
  display: flex;
  gap: 10px;
  align-items: center
}

.comp {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer
}

.comp .icon {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  background: linear-gradient(90deg, #60a5fa, #a78bfa);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700
}

.calendar {
  text-align: center
}

.cal-top {
  background: #ef4444;
  color: white;
  padding: 8px;
  border-radius: 8px
}

.cal-day {
  font-size: 48px;
  font-weight: 700;
  margin: 8px 0
}

.cal-sub {
  color: #666
}

.charts-row {
  display: flex;
  gap: 18px
}

.market-chart {
  flex: 2;
  position: relative
}

.echart {
  width: 100%;
  height: 360px;
}

.chart-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px
}

.index-monitor {
  flex: 1
}

.index-list {
  display: flex;
  gap: 8px;
  margin-bottom: 12px
}

.index-card {
  border-radius: 12px;
  padding: 12px;
  text-align: center
}

.index-card .num {
  font-size: 22px;
  font-weight: 700
}

.rising {
  background: #fff1f2
}

.trending {
  background: #eef2ff
}

.risky {
  background: #fff7ed
}

.badge-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px
}

.badge {
  background: #fff;
  border-radius: 10px;
  padding: 10px;
  display: flex;
  gap: 10px;
  align-items: center;
  cursor: pointer
}

.badge-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: #fde68a;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700
}

/* modal */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center
}

.modal-inner {
  background: white;
  border-radius: 10px;
  padding: 18px;
  width: 420px;
  position: relative
}

.modal-inner .close {
  position: absolute;
  right: 8px;
  top: 8px;
  border: 0;
  background: transparent;
  font-size: 20px
}

.modal-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px
}

.history-hot-index ul {
  list-style-type: none;
  padding-left: 0;
}

.history-hot-index li {
  margin-bottom: 5px;
}

@media (max-width: 900px) {
  .cards-row {
    flex-direction: column
  }

  .charts-row {
    flex-direction: column
  }
}
</style>